package com.jindi.jacococli.biz.business.service;

import com.jindi.jacococli.biz.business.client.GitClient;
import com.jindi.jacococli.biz.config.AppProperties;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.gitlab4j.api.GitLabApi;
import org.gitlab4j.api.GitLabApiException;
import org.gitlab4j.api.models.Project;
import org.gitlab4j.api.models.ProjectFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;

import javax.annotation.Resource;
import java.io.File;
import java.util.List;
import java.util.stream.Collectors;

import static com.jindi.jacococli.biz.constant.Constant.BACKSLASH;

@Component
public class GitLabService implements InitializingBean {

    public static final Logger LOGGER = LoggerFactory.getLogger(GitLabService.class);

    @Resource
    private AppProperties appProperties;

    @Resource
    private GitClient gitClient;

    private GitLabApi gitLabApi;

    public boolean handleProjects(String serviceName, String dir, String projectName) {
        List<Project> projects = projectFindByServiceName(projectName);
        if (CollectionUtils.isEmpty(projects)) {
            LOGGER.info("gitlab search service:{} is empty", serviceName);
            return false;
        }
        projects = projects.stream().filter(project -> StringUtils.equals(serviceName, project.getName())).collect(Collectors.toList());
        return handSingleProject(projects.get(0), dir, serviceName, projectName);
    }


    public List<Project> projectFindByServiceName(String projectName) {
        ProjectFilter projectFilter = new ProjectFilter();
        try {
            String[] serviceArray = projectName.split(BACKSLASH);
            List<Project> projects = gitLabApi.getProjectApi().getProjects(projectFilter.withSearch(serviceArray[serviceArray.length - 1]));
            return projects.stream().filter(project ->
                StringUtils.equals(projectName,  project.getNameWithNamespace().replaceAll(" ", ""))
            ).collect(Collectors.toList());
        } catch (GitLabApiException e) {
            LOGGER.error("gitLabApi.getProjectApi().getProjects error", e);
        }
        return null;
    }

    private boolean handSingleProject(Project project, String dir, String serviceName, String projectName) {
        File projectDir = new File(dir);
        if (!projectDir.exists()) {
            projectDir.mkdirs();
        }
        // 只 clone master
        return gitClient.clone(appProperties.getBranch(projectName), project, projectDir, dir + serviceName);
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        String workSpace = appProperties.getWorkSpace();
        if (!workSpace.endsWith(BACKSLASH)) {
            workSpace = workSpace + BACKSLASH;
        }
        appProperties.setWorkSpace(workSpace);
        gitLabApi = new GitLabApi(appProperties.getGitLabDomain(), appProperties.getAccessToken());
        validate();
    }

    private void validate() {
        Assert.hasText(appProperties.getGitLabDomain(), "gitLabDomain must has text");
        Assert.hasText(appProperties.getAccessToken(), "accessToken must has text");
        Assert.hasText(appProperties.getWorkSpace(), "workSpace must has text");
    }
}
